/*
 * 作者: junmu
 * 时间: 2025-07-22
 */
package com.hzbc.faceattendance.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hzbc.faceattendance.dto.PushMessageQueryRequest;
import com.hzbc.faceattendance.model.PushMessage;
import com.hzbc.faceattendance.model.SystemConfig;
import com.hzbc.faceattendance.repository.PushMessageRepository;
import com.hzbc.faceattendance.service.IWechatPushService;
import com.hzbc.faceattendance.utils.DateRangeValidator;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class WechatPushServiceImpl implements IWechatPushService {

    private static final Logger logger = LoggerFactory.getLogger(WechatPushServiceImpl.class);
    private final TokenManagerService tokenManager;
    @Autowired
    private SystemConfig systemConfig;
    @Autowired
    private PushMessageRepository pushMessageRepository;
    @Autowired
    private RestTemplate restTemplate;

    public static ResponseEntity<String> sendTemplateMessage(String url, String accessToken, Map<String, Object> params) {
        RestTemplate restTemplate = new RestTemplate();
        String body = JSONObject.toJSONString(params);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setContentLength(body.getBytes(StandardCharsets.UTF_8).length);

        HttpEntity<String> httpEntity = new HttpEntity<>(body, headers);
        String apiUrl = url + "?access_token=" + accessToken;

        return restTemplate.postForEntity(apiUrl, httpEntity, String.class);
    }

    @Override
    public void sendAbnormalMessage(String openId, String imageUrl, String content, String deviceName, int type,int enterStatus) {
        // Save push record
        PushMessage message = new PushMessage();
        message.setType(type);
        message.setContent(content);
        message.setEnterStatus(enterStatus);
        message.setImagePath(imageUrl);
        message.setCreateTime(new Date());
        message.setPushStatus(0);
        message.setAddress(deviceName);
        PushMessage pushMessage = pushMessageRepository.save(message);
        if (openId != null && !"".equals(openId)) {
            // First get access token
            String accessToken = getAccessToken();

            // Prepare message data
            Map<String, Object> data = new HashMap<>();
            data.put("touser", openId);
            data.put("template_id", systemConfig.getWechatTemplateId()); // 假设WechatConfig中有getTemplateId方法
            HashMap<String, Object> miniprogramMap = new HashMap<>();
//        data.put("url", systemConfig.getMessageDetailUrl()); // 一般是小程序的地址
            miniprogramMap.put("appid", systemConfig.getUniAppId());
            miniprogramMap.put("pagepath", (systemConfig.getMessageDetailUrl() == null ? "pages/index/index" : systemConfig.getMessageDetailUrl()) + "/" + pushMessage.getId());
            data.put("miniprogram", miniprogramMap); // 这里需要跳转小程序
            Map<String, Object> messageData = new HashMap<>();
            HashMap<String, Object> stringObjectHashMap = new HashMap<>();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年M月d日 HH:mm");
            String formattedTime = LocalDateTime.now().format(formatter);
            stringObjectHashMap.put("value", formattedTime);
            messageData.put("time6", stringObjectHashMap);
            HashMap<String, Object> stringObjectHashMap1 = new HashMap<>();
            stringObjectHashMap1.put("value", deviceName);
            messageData.put("character_string8", stringObjectHashMap1);
            data.put("data", messageData);
            // Send message
            String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
            try {
                logger.error("模板消息请求url:{}.参数:{}", url, JSON.toJSONString(data));
                ResponseEntity<String> mapResponseEntity = sendTemplateMessage(url, accessToken, data);
                logger.info("模板消息响应参数: {}", mapResponseEntity.getBody());
            } catch (HttpClientErrorException e) {
                logger.error("Failed to send message to user ID: {}, error: {}", openId, e.getMessage());
            }
        }else {
            logger.info("用户未关注公众号，不推送消息");
        }

    }

    @Override
    public String getAccessToken() {
//        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
//                + systemConfig.getWechatAppId() + "&secret=" + systemConfig.getWechatAppSecret();
//
//        ResponseEntity<Map> response = restTemplate.getForEntity(url, Map.class);
//        String access_token = (String) response.getBody().get("access_token");
//        systemConfig.setWechatAccessToken(access_token);
        return tokenManager.getAccessToken();
    }

    @Override
    public Page<PushMessage> findByCreateTimeBetween(Date startDate, Date endDate, Pageable pageable) {
        return pushMessageRepository.findByCreateTimeBetween(startDate, endDate, pageable);
    }

    @Override
    public Page<PushMessage> findByTypeAndCreateTimeBetween(Integer type, Date startDate, Date endDate, Pageable pageable) {
        return pushMessageRepository.findByTypeAndCreateTimeBetween(type, startDate, endDate, pageable);
    }

    // 在服务实现类中添加
    @Override
    public Page<PushMessage> findUnprocessedMessages(Date startDate, Date endDate, Pageable pageable) {
        return pushMessageRepository.findByPushStatusAndCreateTimeBetween(0, startDate, endDate, pageable);
    }

    @Override
    public Page<PushMessage> findPushMessagesByTypeAndStatus(PushMessageQueryRequest request, Pageable pageable) {
        Date[] dates = DateRangeValidator.validateAndParseP(request);
        if (request.getType() == null && request.getStatus() == null) {
            return pushMessageRepository.findByWhiteListIsNotNullAndCreateTimeBetween(dates[0], dates[1], pageable);
        } else if (request.getType() == null) {
            return pushMessageRepository.findByPushStatusAndCreateTimeBetween(request.getStatus(), dates[0], dates[1], pageable);
        } else if (request.getStatus() == null) {
            return pushMessageRepository.findByTypeAndCreateTimeBetween(request.getType(), dates[0], dates[1], pageable);
        }
        return pushMessageRepository.findByTypeAndPushStatusAndCreateTimeBetween(request.getType(), request.getStatus(), dates[0], dates[1], pageable);
    }

    @Override
    public PushMessage findById(Long messageId) {
        // 添加调试日志
        logger.debug("Querying message with ID: {}", messageId);

        return pushMessageRepository.findByIduseSql(messageId);
    }

    @Override
    public PushMessage save(PushMessage message) {
        return pushMessageRepository.save(message);
    }
}